/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.commons.core;

import com.fasterxml.jackson.databind.JavaType;
import lombok.var;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 序列化器工具
 */
public class Serializer {

    /**
     * 对象序列化为字符串
     * @param obj 序列化对象
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static String serializeToString(Object obj) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var serialize = SerializerFactory.getSerializer();
        return serialize.serializeToString(obj);
    }

    /**
     * 序列化为byte数组
     * @param obj 序列化对象
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static byte[] serializeToByte(Object obj) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var serialize = SerializerFactory.getSerializer();
        return serialize.serializeToByte(obj);
    }

    /**
     * 序列化到流
      @param stream 输出流
     * @param obj 序列化对象
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static void serializeToStream(OutputStream stream, Object obj) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var serialize = SerializerFactory.getSerializer(stream);
        serialize.serializeToStream(obj);
    }

    /**
     * 从字符串反序列化
     * @param value 反序列化值
     * @param clazz 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(String value, Class<T> clazz) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize.deserialize(value,clazz);
    }

    /**
     * 从字符串反序列化
     * @param value 反序列化值
     * @param type 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(String value, JavaType type) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize.deserialize(value,type);
    }

    /**
     * 从字符串反序列化到泛型集合类型
     * @param value 反序列化的值
     * @param collectionClazz 集合类型
     * @param elementClazzes 集合里泛型
     * @param <T> 返回值类型
     * @return
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(String value,Class<?> collectionClazz, Class<?>... elementClazzes) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize(value,collectionClazz,elementClazzes);
    }

    /**
     * 从byte数组反序列化
     * @param value 反序列化值
     * @param clazz 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(byte[] value, Class<T> clazz) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize.deserialize(value,clazz);
    }

    /**
     * 从byte数组反序列化
     * @param value 反序列化值
     * @param type 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(byte[] value, JavaType type) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize.deserialize(value,type);
    }

    /**
     * 从byte数组反序列化到泛型集合类型
     * @param value 反序列化的值
     * @param collectionClazz 集合类型
     * @param elementClazzes 集合里泛型
     * @param <T> 返回值类型
     * @return
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(byte[] value,Class<?> collectionClazz, Class<?>... elementClazzes) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer();
        return deserialize(value,collectionClazz,elementClazzes);
    }

    /**
     * 从流里反序列化
     * @param inputStream 反序列化流
     * @param clazz 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(InputStream inputStream, Class<T> clazz) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IOException {
        var deserialize = SerializerFactory.getDeserializer(inputStream);
        return deserialize.deserialize(clazz);
    }

    /**
     * 从流里反序列化
     * @param inputStream 反序列化流
     * @param type 返回的类型
     * @param <T> 返回值类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(InputStream inputStream, JavaType type) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IOException {
        var deserialize = SerializerFactory.getDeserializer(inputStream);
        return deserialize.deserialize(type);
    }

    /**
     * 从流里反序列化到泛型集合类型
     * @param inputStream 反序列化流
     * @param collectionClazz 集合类型
     * @param elementClazzes 集合里泛型
     * @param <T> 返回值类型
     * @return
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static <T> T deserialize(InputStream inputStream,Class<?> collectionClazz, Class<?>... elementClazzes) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        var deserialize = SerializerFactory.getDeserializer(inputStream);
        return deserialize.deserialize(collectionClazz,elementClazzes);
    }

}
